package com.fingard.dsp.bank.directbank.mufg01;

import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.math.BigDecimal;
import java.util.List;

public class MUFG01SinglePay extends MUFG01Base implements ISinglePay {

    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        if("1".equals(getBankConfig().getValueAsString("channelFlag"))){
            RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1908.reqHeader);
            RetAtsSglDetail detail = new RetAtsSglDetail();
            //拼接请求报文体
            MUFG01Header header = new MUFG01Header();
            header.transCode="h2h.002.001";
            header.pkgNo = getQryTransID();
            XmlTextWriter xmlReq = new XmlTextWriter();
            writeReqHeader(xmlReq,header);
            xmlReq.writeStartElement("req");
            XElement body =new XElement("row","");
            body.addChild(new XElement("corpSerial",p_req1908.singleDetail.askNumber));// 支付指令 ID
            body.addChild(new XElement("manualType","1"));// 是否需要辅助输入
            body.addChild(new XElement("channelType",p_req1908.singleDetail.sameCity));// 类型 0电汇 1同城
            String payDate=p_req1908.singleDetail.bookDate;
            if(StringHelper.isNullOrEmpty(payDate)){
                payDate=p_req1908.singleDetail.payDate;
            }
            body.addChild(new XElement("valueDate",payDate));// 付款日期
            body.addChild(new XElement("currCode",convertCurToBank(p_req1908.singleDetail.payCur)));// 币种 固定为“CNY
            String payAmount=p_req1908.singleDetail.payAmount;
            if(new BigDecimal(payAmount).subtract(new BigDecimal("0.01")).doubleValue()<0
                    || new BigDecimal(payAmount).subtract(new BigDecimal("9999999999.99")).doubleValue()>0){
                detail.respCode ="-1";
                detail.respInfo = "金额传输有误：金额最小为“0.01”，最大为“99999999.99” ";
                retAtsSingle.writeRetDetail(detail);
                return retAtsSingle;
            }
            body.addChild(new XElement("amount",p_req1908.singleDetail.payAmount));// 金额Double10,2
            body.addChild(new XElement("proposer",""));// 申请人号
            body.addChild(new XElement("accNo",p_req1908.singleDetail.payAct));// 申请人帐号
            body.addChild(new XElement("bankName",AsciiChange(p_req1908.singleDetail.payBankLocation)));// 申请人开户行
            body.addChild(new XElement("accName",AsciiChange(p_req1908.singleDetail.payName)));// 申请人全称
            body.addChild(new XElement("opAccName",AsciiChange(p_req1908.singleDetail.recName)));// 收款人全称
            body.addChild(new XElement("opBankName",AsciiChange(p_req1908.singleDetail.cnapsName)));// 收款人开户行
            body.addChild(new XElement("opBankCode",p_req1908.singleDetail.cnapsCode));// 收款人开户行行号 开户行 CNAPS 行号
            body.addChild(new XElement("opAccNo",p_req1908.singleDetail.recAct));// 收款人帐号
            String recAreaName=p_req1908.singleDetail.recAreaName;//收方区域
            body.addChild(new XElement("opAccProv",recAreaName.substring(0,recAreaName.indexOf("_"))));// 汇入省（市）
            body.addChild(new XElement("opAccCity",recAreaName.substring(recAreaName.indexOf("_")+1)));// 汇入地（市）
            body.addChild(new XElement("usage",AsciiChange(p_req1908.singleDetail.purpose)));// 用途
            body.addChild(new XElement("payType","00"));// 支付类别 00普通汇兑 10工资 20特别目的
            if("1".equals(p_req1908.singleDetail.sameBnk)){
                body.addChild(new XElement("sysFlag","0"));// 跨行标识 0本行 1他行
            }else if("0".equals(p_req1908.singleDetail.sameBnk)){
                body.addChild(new XElement("sysFlag","1"));// 跨行标识 0本行 1他行
            }
            body.addChild(new XElement("tranFlag",p_req1908.singleDetail.paySpd));// 加急标识 0普通 1加急
            body.addChild(new XElement("customerNo",bankFront.corpNo));// 客户编号
            if("1".equals(p_req1908.singleDetail.isPrivate)){
                body.addChild(new XElement("opType","1"));// 收款人种类 0居民机构 1居民个人 2非居民机构 3非居民个人
            }else{
                body.addChild(new XElement("opType","0"));// 收款人种类 0居民机构 1居民个人 2非居民机构 3非居民个人
            }
            body.addChild(new XElement("type1","1"));// 是否为货物贸易核查项下付款 0是 1否
            body.addChild(new XElement("type2",""));// BOP汇款附言
            body.addChild(new XElement("organizeCode",""));// 组织机构代码
            body.addChild(new XElement("nationCode",""));// 收款人常驻国家
            body.addChild(new XElement("type3",""));// 付款类型
            body.addChild(new XElement("type4",""));// 付汇性质
            body.addChild(new XElement("tranCode1",""));// 交易编码1
            body.addChild(new XElement("currAmount1",""));// 相应币种及金额1
            body.addChild(new XElement("postscript1",""));// 交易附言1
            body.addChild(new XElement("tranCode2",""));// 交易编码2
            body.addChild(new XElement("currAmount2",""));// 相应币种及金额2
            body.addChild(new XElement("postscript2",""));// 交易附言2
            body.addChild(new XElement("type5",""));// 是否为保税货物项下付款
            body.addChild(new XElement("contractNo",""));// 合同号
            body.addChild(new XElement("invoiceNo",""));// 发票号
            body.addChild(new XElement("businessNo",""));// 外汇局批件号/备案表号/业务编号
            body.addChild(new XElement("applicant",""));// 申请人姓名
            body.addChild(new XElement("tel",""));// 电话
            nodeAnalysis(p_req1908.singleDetail.srcXElement,body,getCharset());
            xmlReq.writeXElement(body);
            xmlReq.writeEndDocument();
            //发送请求报文
            String[] bankResult = sendToBank(xmlReq.toXmlString());
            //处理响应报文
            if(bankResult[0].length()==0){
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                if(tmpBkReader!=null){
                    String acceptFlag=tmpBkReader.getFirstText("/h2h/respInfo/acceptFlag");//报文受理状态
                    String respCode = tmpBkReader.getFirstText("/h2h/respInfo/respCode");//返回结果码
                    String respInfo = tmpBkReader.getFirstText("/h2h/respInfo/respMsg");//返回结果说明
                    detail.respCode = "0";
                    detail.respInfo = respCode+" "+respInfo;
                    detail.reqSeqID = p_req1908.singleDetail.askNumber;
                    if("-1".equals(acceptFlag)){//报文受理失败
                        detail.transState = "12";//银行受理失败
                    }else {
                        while (tmpBkReader.read("/h2h/resp/row")){
                            String seqId=tmpBkReader.readedXElement.getSingleTextNotNull("corpSerial");//支付流水号
                            if(p_req1908.singleDetail.askNumber.equals(seqId)){
                                detail.transState = tmpBkReader.readedXElement.getSingleTextNotNull("tranStatus");//支付状态
                            }
                        }
                        if(StringHelper.isNullOrEmpty(detail.transState)){
                            detail.transState = "06";//报文受理状态未知，置为处理中，通过1944查证最终结果
                        }
                    }
                    detail.payInfoCode = detail.transState;
                }else{
                    detail.respCode ="-1";
                    detail.respInfo = tmpSbMsg.toString();
                }
            }else if (bankResult[0].equals(ConnState.FAIL)) {
                detail.respCode = "0";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
                detail.transState = PaymentState.FAIL_Payment;
                detail.payInfoCode = bankResult[0];
            }else{
                detail.respCode ="-1";
                detail.respInfo = bankResult[1];
                detail.reqSeqID = p_req1908.singleDetail.askNumber;
            }
            retAtsSingle.writeRetDetail(detail);
            return retAtsSingle;
        }else {
            return null;
        }
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        if("1".equals(getBankConfig().getValueAsString("channelFlag"))){
            RetAtsSingle retAtsSingle = new RetAtsSingle(p_req1944.reqHeader);
            RetAtsSglDetail detail = new RetAtsSglDetail();
            //拼接请求报文体
            MUFG01Header header=new MUFG01Header();
            header.transCode="h2h.002.007";
            header.pkgNo = getQryTransID();
            XmlTextWriter xmlReq = new XmlTextWriter();
            writeReqHeader(xmlReq,header);
            xmlReq.writeStartElement("req");
            XElement body =new XElement("row","");
            body.addChild(new XElement("corpSerial", p_req1944.askNumber));//交易流水号
            xmlReq.writeXElement(body);
            xmlReq.writeEndDocument();
            //发送请求报文并获取响应
            String[] bankResult = sendToBank(xmlReq.toXmlString());
            //处理响应
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String acceptFlag=tmpBkReader.getFirstText("/h2h/respInfo/acceptFlag");//报文受理状态
                    String respCode = tmpBkReader.getFirstText("/h2h/respInfo/respCode");//返回结果码
                    String respInfo = tmpBkReader.getFirstText("/h2h/respInfo/respMsg");//返回结果说明
                    if("1".equals(acceptFlag)){//受理成功
                        while (tmpBkReader.read("/h2h/resp/row")){
                            if ("1".equals(tmpBkReader.readedXElement.getSingleTextNotNull("statusFlag"))) {//查询处理状态 1有 -1无
                                List<XElement> respList = tmpBkReader.readedXElement.getChildList("list");
                                for(XElement list:respList){
                                    detail.respCode = "0";
                                    detail.respInfo = list.getSingleTextNotNull("sfrespCode")
                                            +"："+list.getSingleTextNotNull("sfrespMsg");
                                    detail.transState = list.getSingleTextNotNull("tranStatus");
                                    detail.reqSeqID = p_req1944.askNumber;
                                    detail.payInfoCode = detail.transState;
                                }
                            }else {
                                detail.respCode = "-1";
                                detail.respInfo = "根据查询条件没有得到对象记录";
                            }
                        }
                    }else {//受理未响应或受理失败
                        detail.respCode="-1";
                        detail.respInfo=respCode+"："+respInfo;
                    }
                }else {
                    detail.respCode = "-1";
                    detail.respInfo = tmpSbMsg.toString();
                }
            }else {
                detail.respCode = "-1";
                detail.respInfo = bankResult[1];
            }
            retAtsSingle.writeRetDetail(detail);
            return retAtsSingle;
        }else {
            return null;
        }
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
